package com.zzyl.nursing.service.impl;

import java.util.*;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.graphbuilder.curve.ValueVector;
import com.zzyl.common.core.domain.R;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.framework.web.service.TokenService;
import com.zzyl.nursing.dto.DeviceDataPointDto;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.ElderDto;
import com.zzyl.nursing.dto.FamilyMemberDto;
import com.zzyl.nursing.mapper.DeviceDataMapper;
import com.zzyl.nursing.mapper.*;
import com.zzyl.nursing.service.IDeviceService;
import com.zzyl.nursing.service.WechatService;
import com.zzyl.nursing.vo.DeviceFunctionHistoryQueryVo;
import com.zzyl.nursing.vo.FamilyMemberElderVo;
import com.zzyl.nursing.vo.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.service.IFamilyMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 老人家属Service业务层处理
 *
 * @author ruoyi
 * @date 2025-06-05
 */
@Service
public class FamilyMemberServiceImpl extends ServiceImpl<FamilyMemberMapper, FamilyMember> implements IFamilyMemberService {
    @Autowired
    private FamilyMemberMapper familyMemberMapper;

    @Autowired
    private WechatService wechatService;

    @Autowired
    private TokenService tokenService;
    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private FamilyMemberElderMapper familyMemberElderMapper;

    @Autowired
    private RoomMapper roomMapper;

    @Autowired
    private IDeviceService deviceService;

    @Autowired
    private BedMapper bedMapper;


    @Autowired
    private DeviceDataMapper deviceDataMapper;

    /**
     * 查询老人家属
     *
     * @param id 老人家属主键
     * @return 老人家属
     */
    @Override
    public FamilyMember selectFamilyMemberById(Long id) {
        return getById(id);
    }

    /**
     * 查询老人家属列表
     *
     * @param familyMember 老人家属
     * @return 老人家属
     */
    @Override
    public List<FamilyMember> selectFamilyMemberList(FamilyMember familyMember) {
        return familyMemberMapper.selectFamilyMemberList(familyMember);
    }

    /**
     * 新增老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int insertFamilyMember(FamilyMember familyMember) {
        return save(familyMember) ? 1 : 0;
    }

    /**
     * 修改老人家属
     *
     * @param familyMember 老人家属
     * @return 结果
     */
    @Override
    public int updateFamilyMember(FamilyMember familyMember) {
        return updateById(familyMember) ? 1 : 0;
    }

    /**
     * 批量删除老人家属
     *
     * @param ids 需要删除的老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除老人家属信息
     *
     * @param id 老人家属主键
     * @return 结果
     */
    @Override
    public int deleteFamilyMemberById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    @Override
    public LoginVo login(FamilyMemberDto familyMemberDto) {
        //根据appid、app secret、code得到openId
        String openid = wechatService.getOpenid(familyMemberDto.getCode());
        //根据openid到数据库中查询用户
        LambdaQueryWrapper<FamilyMember> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FamilyMember::getOpenId, openid);
        FamilyMember familyMember = familyMemberMapper.selectOne(queryWrapper);
        //根据phoneCode获取用户手机号
        String phone = wechatService.getPhone(familyMemberDto.getPhoneCode());
        //判断查询到的用户信息是否为空，如果为空，则需要新建用户信息存到数据库中，如果不为空，则更新手机号
        if (familyMember == null) {
            familyMember = new FamilyMember();
            familyMember.setGender(0);
            familyMember.setPhone(phone);
            familyMember.setOpenId(openid);
            familyMember.setName("张宇豪");
            familyMemberMapper.insert(familyMember);
        } else if (phone != null && !familyMember.getPhone().equals(phone)) {
            LambdaUpdateWrapper<FamilyMember> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(FamilyMember::getPhone, phone)
                    .eq(FamilyMember::getOpenId, familyMember.getOpenId());
            familyMemberMapper.update(familyMember, updateWrapper);
        }
        //封装jwt加密结果返回
        Map<String, Object> map = new HashMap<>();
        map.put("userId", familyMember.getId());
        map.put("nickName", familyMember.getName());
        String token = tokenService.createToken(map);

        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setNickName(familyMember.getName());
        return loginVo;
    }

    @Override
    public void add(ElderDto elderDto) {
        Elder elder = elderMapper.selectOne(new QueryWrapper<Elder>()
                .eq("name", elderDto.getName())
                .eq("id_card_no", elderDto.getIdCard()));
        if (elder == null) {
            throw new RuntimeException("该老人不存在");
        }
        elderDto.setCreateTime(new Date());
        elderDto.setUpdateTime(new Date());
        //获取登录用户id
        elderDto.setFamilyMemberId(UserThreadLocal.getUserId());
        elderDto.setElderId(elder.getId());
        familyMemberElderMapper.insert(elderDto);

    }

    @Override
    public List<ElderDto> getMyFamily() {
        ElderDto familyMember = new ElderDto();
        familyMember.setFamilyMemberId(UserThreadLocal.getUserId());
        List<ElderDto> list = familyMemberElderMapper.getMyElder(familyMember.getFamilyMemberId());
        if (list == null) {
            throw new RuntimeException("该用户没有绑定老人");
        }
        list.forEach(elderDto -> {
            Long elderId = elderDto.getElderId();
            String name = elderMapper.selectById(elderId).getName();
            elderDto.setName(name);
        });
        return list;
    }

    @Override
    public List<FamilyMemberElderVo> listByPage(Integer pageNum, Integer pageSize) {
        // 获取当前用户
        Integer startNum = (pageNum - 1) * pageSize;
        Long userId = UserThreadLocal.getUserId();

        List<ElderDto> myElder = familyMemberElderMapper.getMyElderPage(userId, startNum, pageSize);
        if (myElder.isEmpty()) {
            throw new RuntimeException("没有绑定家人");
        }
        List<FamilyMemberElderVo> familyMemberElderVos = new ArrayList<>();
        myElder.forEach(elderDto -> {
            FamilyMemberElderVo familyMemberElderVo = new FamilyMemberElderVo();
            Long elderId = elderDto.getElderId();
            //添加老人id
            familyMemberElderVo.setElderId(elderId);
            familyMemberElderVo.setMremark(elderDto.getRemark());
            familyMemberElderVo.setMid(elderDto.getId());
            Elder elder = elderMapper.selectElderById(elderId);

            familyMemberElderVo.setImage(elder.getImage());
            familyMemberElderVo.setBedNumber(elder.getBedNumber());
            Bed bed = bedMapper.selectById(elder.getBedId());
            Room room = roomMapper.selectRoomById(bed.getRoomId());
            familyMemberElderVo.setTypeName(room.getTypeName());
            Device one = deviceService.lambdaQuery().eq(Device::getBindingLocation, elder.getId())
                    .eq(Device::getPhysicalLocationType, -1).one();
            if (ObjectUtil.isNotEmpty(one)) {
                familyMemberElderVo.setIotId(one.getIotId());
                familyMemberElderVo.setDeviceName(one.getDeviceName());
                familyMemberElderVo.setProductKey(one.getProductKey());
            }
            familyMemberElderVos.add(familyMemberElderVo);

        });


        return familyMemberElderVos;
    }




    /**
     * 按天统计查询指标数据
     * @param deviceFunctionHistoryQueryVo
     * @return
     */
    @Override
    public List<DeviceDataPointDto> queryDeviceDataListByDay(DeviceFunctionHistoryQueryVo deviceFunctionHistoryQueryVo) {
        // 查询数据库 按天查询数据
        Long startTime = deviceFunctionHistoryQueryVo.getStartTime();
        Long endTime = deviceFunctionHistoryQueryVo.getEndTime();
        List<DeviceDataPointDto> deviceDataPointDtoList = deviceDataMapper.queryDeviceDataListByDay(deviceFunctionHistoryQueryVo.getIotId(),
                deviceFunctionHistoryQueryVo.getFunctionId(),
                LocalDateTimeUtil.of(startTime),
                LocalDateTimeUtil.of(startTime));

        // 整理数据
        // 初始化一个空的, 全的数据列表
        List<DeviceDataPointDto> list = DeviceDataPointDto.dayIstance(LocalDateTimeUtil.of(startTime));

        // 把结果数据转换成map集合
        Map<String, Double> map = deviceDataPointDtoList.stream().collect(Collectors.toMap(DeviceDataPointDto::getDateTime, DeviceDataPointDto::getDataValue));

        list.forEach(d -> {
            // 判断DeviceData的DateTime是否为空， 赋值val到DeviceData中
            Double dataValue = map.get(d.getDateTime() == null ? 0.0 : map.get(d.getDateTime()));
            d.setDataValue(dataValue);
        });

        return list;
    }

    @Override
    public List<DeviceDataPointDto> queryDeviceDataListByWeek(DeviceFunctionHistoryQueryVo deviceFunctionHistoryQueryVo) {
        // 查询数据库 按周查询数据
        Long startTime = deviceFunctionHistoryQueryVo.getStartTime();
        Long endTime = deviceFunctionHistoryQueryVo.getEndTime();
        List<DeviceDataPointDto> deviceDataPointDtoList = deviceDataMapper.queryDeviceDataListByWeek(deviceFunctionHistoryQueryVo.getIotId(),
                deviceFunctionHistoryQueryVo.getFunctionId(),
                LocalDateTimeUtil.of(startTime),
                LocalDateTimeUtil.of(startTime));

        // 整理数据
        // 初始化一个空的, 全的数据列表
        List<DeviceDataPointDto> list = DeviceDataPointDto.dayIstance(LocalDateTimeUtil.of(startTime));

        // 把结果数据转换成map集合
        Map<String, Double> map = deviceDataPointDtoList.stream().collect(Collectors.toMap(DeviceDataPointDto::getDateTime, DeviceDataPointDto::getDataValue));

        list.forEach(d -> {
            // 判断DeviceData的DateTime是否为空， 赋值value到DeviceData中
            Double dataValue = map.get(d.getDateTime() == null ? 0.0 : map.get(d.getDateTime()));
            d.setDataValue(dataValue);
        });

        return list;
    }
}
